#pragma once
#include<iostream>
#include<vector>
#include<semaphore.h>
using std::cout;
using std::endl;
using std::vector;
const  int gDefaultCap=5;

template<class T>
class ringQueue{
    public:
        ringQueue(const int cap=gDefaultCap)        
            :_ringQueue(cap)
            ,_pIndex(0)
            ,_cIndex(0)
            {
                sem_t_init(&_roomSem,0,_ringQueue.size());
                sem_t_init(&_dataSem,0,0);
            }
        ~ringQueue()
        {
            sem_destroy(&_roomSem);
            sem_destroy(&_dataSem);
        }

        void push(const T &in)
        {
            sem_wait(&_roomSem);
            _ringQueue[_pIndex]=in;
            sem_post(&_dataSem);
            _pIndex++;
            _pIndex %= _ringQueue.size();
        }

        T pop()
        {
            sem_wait(&_dataSem);
            T tmp=_roomSem[_cIndex];
            sem_post(&_roomSem);
            _cIndex--;
            _cIndex %=_ringQueue.size();
            return tmp;
        }
    private:
        vector<T> _ringQueue;
        sem_t _roomSem;
        sem_t _dataSem;
        uint32_t _pIndex;
        uint32_t _cIndex;
};
